import 'package:date_format/date_format.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wu_you/l10n/messages.dart';
import 'package:wu_you/res/colors.dart';
import 'package:wu_you/state/bloc/http_bloc.dart';
import 'package:wu_you/utils/utils.dart';
import 'package:wu_you/widgets/loading_view.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';

import 'http_status_widget.dart';

typedef LoadDataCallback = Function(BuildContext context, int page);

class HttpListWidget<T, B extends HttpBloc<List<T>>> extends StatefulWidget {
  final bool enablePullDown;
  final bool enablePullUp;
  final BlocCreator<B> creator;
  final HttpSuccessBuilder<List<T>> successBuilder;
  final WidgetBuilder emptyBuilder;
  final LoadDataCallback onObtainData;
  final bool showNoDataText;
  final Function(RefreshController) onCreated;
  final bool showLoading;
  final bool pointEmpty;
  final bool canceLoading;
  HttpListWidget({
    Key key,
    @required this.creator,
    @required this.onObtainData,
    this.successBuilder,
    this.emptyBuilder,
    this.enablePullDown = true,
    this.enablePullUp = true,
    this.showNoDataText = true,
    this.onCreated,
    this.showLoading,
    this.pointEmpty = false,
    this.canceLoading = true,
  })  : assert(creator != null),
        assert(onObtainData != null),
        super(key: key);

  @override
  _HttpListWidgetState<T, B> createState() => _HttpListWidgetState<T, B>();
}

class _HttpListWidgetState<T, B extends HttpBloc<List<T>>> extends State<HttpListWidget<T, B>> {
  final RefreshController _refreshController = RefreshController(initialRefresh: true);

  int _page = 1;
  List<T> _data = [];
  bool _first = false;
  @override
  void initState() {
    super.initState();
    widget.onCreated?.call(_refreshController);
    // Future.delayed(Duration(milliseconds: 500),(){
    //   widget.onObtainData.call(context, _page);
    // });
  }

  var message;
  @override
  Widget build(BuildContext context) {
    message = AppLocalizations.of(context);
    return BlocProvider<B>(
      create: widget.creator,
      child: BlocBuilder<B, HttpState>(
        builder: (context, state) {
          _updateState(state,context);
          Widget child =  SmartRefresher(
            enablePullDown: widget.enablePullDown,
            enablePullUp: widget.enablePullUp,
            header: ClassicHeader(
              completeText: '${message['RefreshComplete']}',
              failedText: '${message['RefreshError']}',
              idleText: '${message['pullDown']}',
              refreshingText: '${message['refreshing']}...',
              releaseText: '${message['RfRefresh']}',
            ),
            footer: ClassicFooter(
              idleText: '${message['pullUp']}',
              failedText: '${message['loadError']}',
              loadingText: '${message['loading']}...',
              noDataText: widget.showNoDataText ? '${message['noMore']}' : '',
              canLoadingText: '${message['RfLoad']}',
            ),
            controller: _refreshController,
            child: _buildByState(context, state),
            onRefresh: () {
              _first = true;
              _page = 1;
              widget.onObtainData.call(context, _page);
            },
            onLoading: () {
              widget.onObtainData.call(context, _page);
            },
          );
          return child;
        },
      ),
    );
  }

  void _updateState(HttpState state,BuildContext context) {
    if (state is HttpLoading) {
      return;
    }
    HttpEvent httpEvent = state.httpEvent;
    if (!(httpEvent is PageSizeHttpEvent)) {
      return;
    }
    PageSizeHttpEvent event = httpEvent as PageSizeHttpEvent;
    int page = event.page;
    if (page == 1) {
      _onRefreshReturn(state);
    } else {
      _onLoadMoreReturn(state);
    }
  }

  void _onRefreshReturn(HttpState state) {
    if (state is HttpFailure) {
      _refreshController.refreshFailed();
      return;
    }
    _refreshController.resetNoData();
    _refreshController.refreshCompleted();

    if (state is HttpSuccessWithData) {
      // if(_page == 1){
      //   Navigator.pop(context);
      // }
      if(_data != null) {
        _data.clear();
        _data.addAll(state.data);
        _page = 2;
      }
      PageSizeHttpEvent event = state.httpEvent as PageSizeHttpEvent;
      if (_data.length < event.size) {
        _refreshController.loadNoData();
      }
      return;
    }

    if (state is HttpSuccess) {
      _data.clear();
      _refreshController.loadNoData();
      return;
    }
  }

  void _onLoadMoreReturn(HttpState state) {
    if (state is HttpFailure) {
      _refreshController.loadFailed();
      return;
    }
    _refreshController.loadComplete();
    if (state is HttpSuccessWithData) {

      if(_refreshController.isLoading){
        _data.addAll(state.data);
        // print("loadPage=$_page _data=${_data.length}");
        _page+=1;
      }
      PageSizeHttpEvent event = state.httpEvent as PageSizeHttpEvent;
      if (state.data.length < event.size) {
        _refreshController.loadNoData();
      }
      return;
    }
    _refreshController.loadNoData();
  }

  Widget _buildByState(BuildContext context, HttpState state) {

    if(state is HttpLoading && widget.showLoading != null && _refreshController.isRefresh == false && _refreshController.isLoading == false&& _first == true){

      return
        LoadingView();
    }
    if (_data != null && _data.isNotEmpty) {
      return widget.successBuilder(context, _data);
    }
    Widget child;
    try{
      child = widget.emptyBuilder(context);
    }catch(e){

    }
    if(state is HttpLoading && _refreshController.isLoading == false){
      if(!widget.canceLoading){
        return null;
      }
      return LoadingView(color: Colors.transparent,);
    }
    if(child != null && widget.pointEmpty){
      return child;
    }
    return  Column(mainAxisAlignment: MainAxisAlignment.center, children: [
      Image.asset(Utils.getImgPath("ic_empty",), width: 60,
        fit: BoxFit.fitWidth,),
      SizedBox(height: 10,),
      Text("${message['noData']}",
        style: TextStyle(color: AppColors.textHintColor, fontSize: 14),),
    ],);

  }
}
